package com.xdty.fastInput;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.xdty.fastInput.utils.JFrameUtil;
import lombok.Data;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

@Data
public class FastInputApp extends JFrame {

    private JTable table;
    private DefaultTableModel tableModel;
    private final String KEY_PREFIX = "ctrl+";

    public static boolean ctrlIsActive = false;
    public static boolean keyIsActive = false;
    public static String pressedOtherKey = "";
    private final List<Map<String, String>> isAction = new ArrayList<>();
    private final String saveDataPath = getClass().getClassLoader().getResource("tableData.txt").getPath();
    private File file = new File(saveDataPath);
    private boolean allIsAction = false;

    public FastInputApp() throws IOException {
        programeMain();
    }

    private void programeMain() throws IOException {
        setTitle("FastInput");
        setSize(1700, 1000);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null); // 居中显示窗口
        setIconImage(ImageIO.read(new File(getClass().getClassLoader().getResource("favicon.ico").getPath())));

        // 创建面板
        JPanel panel = new JPanel(new BorderLayout());

        // 创建按钮面板
        JPanel buttonPanel = new JPanel(new FlowLayout());
        JButton addButton = new JButton("新增");
        JButton enableButton = new JButton("启用");
        JButton enableAllButton = new JButton("一键启用");
        JButton deleteButton = new JButton("删除");
        JButton saveButton = new JButton("保存"); // 新增保存按钮

        buttonPanel.add(addButton);
        buttonPanel.add(enableButton);
        buttonPanel.add(enableAllButton);
        buttonPanel.add(deleteButton);
        buttonPanel.add(saveButton); // 添加保存按钮到按钮面板

        // 添加按钮事件监听器
        addButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                addRow();
            }
        });

        // 启用按钮事件监听器
        enableButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int selectedRow = table.getSelectedRow();
                if (selectedRow != -1) {
                    Object[] tableDataByRow = JFrameUtil.getTableDataByRow(tableModel, selectedRow);
                    if (StrUtil.isBlank((String) tableDataByRow[1]) || KEY_PREFIX.equals((String) tableDataByRow[1])) {
                        JOptionPane.showMessageDialog(table, "请先决定快捷键。");
                        return;
                    }

                    if (StrUtil.isBlank((String) tableDataByRow[2])) {
                        JOptionPane.showMessageDialog(table, "请决定内容。");
                        return;
                    }

                    toggleEnable(selectedRow);
                } else {
                    JOptionPane.showMessageDialog(table, "请选择一行进行操作。");
                }
            }
        });

        enableAllButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int rowCount = tableModel.getRowCount();
                List<Map<String, String>> keyList = new ArrayList<>();
                for (int row = 0; row < rowCount; row++) {
                    Object[] tableDataByRow = JFrameUtil.getTableDataByRow(tableModel, row);
                    if (StrUtil.isBlank((String) tableDataByRow[1]) || KEY_PREFIX.equals((String) tableDataByRow[1])) {
                        continue;
                    }

                    if (StrUtil.isBlank((String) tableDataByRow[2])) {
                        continue;
                    }

                    //toggleEnable(row);
                    tableModel.setValueAt(!allIsAction?"已启用":"未启用", row, 3);
                    keyList.add(new HashMap<String,String>(){{put((String) tableDataByRow[1],(String) tableDataByRow[2]);}});
                }
                isAction.clear();
                if (!allIsAction){
                    isAction.addAll(keyList);
                }
                enableAllButton.setText(allIsAction?"一键启用":"一键关闭");
                allIsAction = !allIsAction;
            }
        });

        // 删除按钮事件监听器
        deleteButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int selectedRow = table.getSelectedRow();
                if (selectedRow != -1) {
                    deleteRow(selectedRow);
                } else {
                    JOptionPane.showMessageDialog(table, "请选择一行进行操作。");
                }
            }
        });

        // 保存按钮事件监听器
        saveButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    saveTableDataToFile();
                } catch (IOException ioException) {
                    JOptionPane.showMessageDialog(table, "保存出错。");
                }
            }
        });

        String contentJsonStr = FileUtil.readString(file, "UTF-8");
        Object[][] datas = null;
        if (StrUtil.isNotBlank(contentJsonStr)){
            List<List> lists =  JSONArray.parseArray(contentJsonStr,List.class);
            datas = new Object[lists.size()][4];
            for (int i = 0; i < lists.size(); i++) {
                Object[] objects = lists.get(i).toArray();
                datas[i] = objects;
            }
        }
        Object[] columnNames = new Object[]{"序号", "快捷键", "内容", "启用"};
        // 创建表格模型
        tableModel = ObjectUtil.isNotNull(datas)? new DefaultTableModel(datas,columnNames) : new DefaultTableModel(columnNames, 0) {
            @Override
            public boolean isCellEditable(int row, int column) {
                // 允许编辑“快捷键”、“内容”和“启用”列
                return column == 1 || column == 2;
            }

            @Override
            public Class<?> getColumnClass(int columnIndex) {
                return super.getColumnClass(columnIndex);
            }
        };

        // 创建表格
        table = new JTable(tableModel);

        // 设置行高
        table.setRowHeight(30);

        // 设置单元格内容居中
        DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
        centerRenderer.setHorizontalAlignment(JLabel.CENTER);
        table.setDefaultRenderer(Object.class, centerRenderer);

        // 设置快捷键列的编辑器
        JTextField jTextField = new JTextField();

        jTextField.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent e) {
                // 在这里处理失去焦点时的逻辑
                String text = jTextField.getText();
                text = text.replaceAll("\\s+", "");
                if (!text.startsWith(KEY_PREFIX) || KEY_PREFIX.equals(text)) {
                    JOptionPane.showMessageDialog(table, "快捷键格式错误");
                    jTextField.setText(KEY_PREFIX);
                    return;
                }

                int selectedRow = table.getSelectedRow();
                List<Object[]> allTableData = JFrameUtil.getAllTableData(tableModel);
                Object[] selectedData = JFrameUtil.getTableDataByRow(tableModel, selectedRow);
                if (ObjectUtil.isNotEmpty(allTableData)){
                    String finalText = text;
                    List<Object[]> repeatDatas = allTableData.stream().filter(dataArr -> !((Integer) dataArr[0]).equals((Integer) selectedData[0]) && ((String) dataArr[1]).equals(finalText)).collect(Collectors.toList());
                    if (ObjectUtil.isNotEmpty(repeatDatas)){
                        jTextField.setText(KEY_PREFIX);
                        JOptionPane.showMessageDialog(table, "快捷键已存在");
                        return;
                    }
                }
            }

            @Override
            public void focusGained(FocusEvent e) {
                // 在这里处理获得焦点时的逻辑
                jTextField.setText(KEY_PREFIX);
            }
        });
        table.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(jTextField));

        // 添加焦点监听器到内容列
        table.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(new JTextField()) {
            @Override
            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
                JTextField textField = (JTextField) super.getTableCellEditorComponent(table, value, isSelected, row, column);
                String shortcut = (String) table.getValueAt(row, 1);
                if (shortcut == null || shortcut.isEmpty() || KEY_PREFIX.equals(shortcut)) {
                    JOptionPane.showMessageDialog(table, "请先决定快捷键。");
                    return null;
                }
                return textField;
            }
        });

        // 添加焦点监听器到内容列
        table.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                int selectedRow = table.getSelectedRow();
                int selectedColumn = table.getSelectedColumn();
                if (selectedColumn == 2 && selectedRow != -1) { // 内容列
                    String shortcut = (String) table.getValueAt(selectedRow, 1);
                    if (shortcut == null || shortcut.isEmpty()) {
                        JOptionPane.showMessageDialog(table, "请先决定快捷键。");
                        table.changeSelection(selectedRow, 1, false, false); // 切换到快捷键列
                    }
                }
            }
        });

        JScrollPane scrollPane = new JScrollPane(table);

        // 将按钮面板和表格添加到主面板
        panel.add(buttonPanel, BorderLayout.NORTH);
        panel.add(scrollPane, BorderLayout.CENTER);

        // 设置主面板为窗口的内容面板
        setContentPane(panel);
    }

    private void addRow() {
        int nextIndex = tableModel.getRowCount() + 1;
        tableModel.addRow(new Object[]{nextIndex, "", "", "未启用"});
    }

    private void deleteRow(int row) {
        if (row >= 0) {
            tableModel.removeRow(row);
            // 更新序号
            for (int i = 0; i < tableModel.getRowCount(); i++) {
                tableModel.setValueAt(i + 1, i, 0);
            }
        }
    }

    private void toggleEnable(int row) {
        String currentStatus = (String) tableModel.getValueAt(row, 3);
        if ("未启用".equals(currentStatus)) {
            isAction.add(new HashMap<String, String>() {{
                put((String) tableModel.getValueAt(row, 1), (String) tableModel.getValueAt(row, 2));
            }});
            tableModel.setValueAt("已启用", row, 3);
        } else {
            List<Map<String, String>> list = isAction.stream()
                    .filter(map -> !map.keySet().contains((String) tableModel.getValueAt(row, 1)))
                    .collect(Collectors.toList());
            isAction.clear();
            isAction.addAll(list);
            tableModel.setValueAt("未启用", row, 3);
        }
    }

    public List<String> getAllTableKeys() {
        List<String> data = new ArrayList<>();
        int rowCount = tableModel.getRowCount();
        for (int row = 0; row < rowCount; row++) {
            data.add((String) tableModel.getValueAt(row, 1));
        }
        return data;
    }

    // 新增保存表格数据的方法
    private void saveTableDataToFile() throws IOException {
        if (!file.exists()){
            file.createNewFile();
        }

        FileUtil.writeUtf8String("",file);

        List<Object[]> allTableData = JFrameUtil.getAllTableData(tableModel);
        for (Object[] allTableDatum : allTableData) {
            allTableDatum[3] = "未启用";
        }
        FileUtil.writeString(JSONArray.toJSONString(allTableData),file,"UTF-8");
        JOptionPane.showMessageDialog(table, "保存成功");
    }
}
